Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 538bee4526eb49ee7a2b62f826c09fa2c461e900


Parents : 6e4baf3
Author : Mark Qvist <mark@unsigned.io>
Date : 2021-08-28T20:12:03+02:00

Improved browser functionality.

Changes

5 files changed, 104 insertions(+), 22 deletions(-)

M setup.py +2 -2

Diff

diff --git a/nomadnet/ui/TextUI.py b/nomadnet/ui/TextUI.py
index c6700b9..d41981f 100644
--- a/nomadnet/ui/TextUI.py
+++ b/nomadnet/ui/TextUI.py
@@ -20,7 +20,7 @@ THEMES = {
# Style name # 16-color style # Monochrome style # 88, 256 and true-color style
('heading', 'light gray,underline', 'default', 'underline', 'g93,underline', 'default'),
('menubar', 'black', 'light gray', 'standout', '#111', '#bbb'),
- ('scrollbar', 'black', 'light gray', 'standout', '#444', 'default'),
+ ('scrollbar', 'light gray', 'default', 'standout', '#444', 'default'),
('shortcutbar', 'black', 'light gray', 'standout', '#111', '#bbb'),
('body_text', 'white', 'default', 'default', '#ddd', 'default'),
('error_text', 'dark red', 'default', 'default', 'dark red', 'default'),
@@ -38,10 +38,13 @@ THEMES = {
("list_off_focus", "black", "dark gray", "standout", "#111", "dark gray"),
("list_trusted", "light green", "default", "default", "#6b2", "default"),
("list_focus_trusted", "black", "light gray", "standout", "#180", "#bbb"),
- ("list_unknown", "dark gray", "default", "default", "light gray", "default"),
- ("list_normal", "dark gray", "default", "default", "light gray", "default"),
+ ("list_unknown", "dark gray", "default", "default", "#bbb", "default"),
+ ("list_normal", "dark gray", "default", "default", "#bbb", "default"),
("list_untrusted", "dark red", "default", "default", "dark red", "default"),
("list_focus_untrusted", "black", "light gray", "standout", "#810", "#bbb"),
+ ("topic_list_normal", "white", "default", "default", "#ddd", "default"),
+ ("progress_full", "black", "light gray", "standout", "#111", "#bbb"),
+ ("progress_empty", "light gray", "default", "default", "#ddd", "default"),
],
}
}
@@ -68,6 +71,8 @@ GLYPHS = {
("divider1", "-", "\u2504", "\u2504"),
("peer", "P", "\U0001F464", "\uf415"),
("node", "N", "\U0001F5A5", "\uf502"),
+ ("page", "", "\U0001F5B9", "\uf719 "),
+ ("speed", "", "\U0001F5B9", "\uf9c4"),
("decoration_menu", "", "", " \uf93a"),
}

diff --git a/nomadnet/ui/textui/Browser.py b/nomadnet/ui/textui/Browser.py
index 4e506b6..88d467c 100644
--- a/nomadnet/ui/textui/Browser.py
+++ b/nomadnet/ui/textui/Browser.py
@@ -53,6 +53,9 @@ class Browser:
self.link = None
self.status = Browser.DISCONECTED
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
self.page_data = None
self.displayed_page_data = None
self.auth_identity = auth_identity
@@ -78,7 +81,7 @@ class Browser:
return RNS.hexrep(self.destination_hash, delimit=False)+":"+path
def handle_link(self, link_target):
- RNS.log("Browser handling link to: "+str(link_target))
+ RNS.log("Browser handling link to: "+str(link_target), RNS.LOG_DEBUG)
try:
self.retrieve_url(link_target)
except Exception as e:
@@ -101,7 +104,13 @@ class Browser:
self.display_widget = urwid.AttrMap(urwid.LineBox(self.frame, title="Remote Node"), "inactive_text")
def make_status_widget(self):
- return urwid.Pile([urwid.Divider(self.g["divider1"]), urwid.Text(self.status_text())])
+ if self.response_progress > 0:
+ pb = ResponseProgressBar("progress_empty" , "progress_full", current=self.response_progress, done=1.0, satt=None)
+ widget = urwid.Pile([urwid.Divider(self.g["divider1"]), pb])
+ else:
+ widget = urwid.Pile([urwid.Divider(self.g["divider1"]), urwid.Text(self.status_text())])
+
+ return widget
def make_control_widget(self):
return urwid.Pile([urwid.Text(self.g["node"]+" "+self.current_url()), urwid.Divider(self.g["divider1"])])
@@ -119,9 +128,14 @@ class Browser:
("weight", 0.5, urwid.Text(" "))
])
- pile = urwid.Pile([
- urwid.Text("!\n\n"+self.status_text()+"\n", align="center"),
- columns
+ if len(self.attr_maps) > 0:
+ pile = urwid.Pile([
+ urwid.Text("!\n\n"+self.status_text()+"\n", align="center"),
+ columns
+ ])
+ else:
+ pile = urwid.Pile([
+ urwid.Text("!\n\n"+self.status_text(), align="center")
])
return urwid.Filler(pile, "middle")
@@ -139,16 +153,21 @@ class Browser:
if self.status == Browser.DONE:
self.browser_footer = self.make_status_widget()
self.update_page_display()
+
elif self.status <= Browser.REQUEST_SENT:
if len(self.attr_maps) == 0:
self.browser_body = urwid.Filler(urwid.Text("Retrieving\n["+self.current_url()+"]", align="center"), "middle")
+
self.browser_footer = self.make_status_widget()
+
elif self.status == Browser.REQUEST_FAILED:
self.browser_body = self.make_request_failed_widget()
self.browser_footer = urwid.Text("")
+
elif self.status == Browser.REQUEST_TIMEOUT:
self.browser_body = self.make_request_failed_widget()
self.browser_footer = urwid.Text("")
+
else:
pass
@@ -172,6 +191,10 @@ class Browser:
self.attr_maps = []
self.status = Browser.DISCONECTED
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
+
self.update_display()
@@ -264,6 +287,7 @@ class Browser:
now = time.time()
if now > pr_time+self.timeout:
self.request_timeout()
+ return
time.sleep(0.25)
@@ -286,6 +310,7 @@ class Browser:
now = time.time()
if now > l_time+self.timeout:
self.request_timeout()
+ return
time.sleep(0.25)
@@ -293,12 +318,17 @@ class Browser:
# Send the request
self.status = Browser.REQUESTING
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
+
self.update_display()
receipt = self.link.request(
self.path,
data = None,
response_callback = self.response_received,
failed_callback = self.request_failed,
+ progress_callback = self.response_progressed,
timeout = self.timeout
)
@@ -328,6 +358,8 @@ class Browser:
self.page_data = request_receipt.response
self.markup = self.page_data.decode("utf-8")
self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self)
+ self.response_progress = 0
+
self.update_display()
except Exception as e:
RNS.log("An error occurred while handling response. The contained exception was: "+str(e))
@@ -337,18 +369,46 @@ class Browser:
if request_receipt != None:
if request_receipt.request_id == self.last_request_id:
self.status = Browser.REQUEST_FAILED
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
+
self.update_display()
else:
self.status = Browser.REQUEST_FAILED
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
+
self.update_display()
def request_timeout(self, request_receipt=None):
self.status = Browser.REQUEST_TIMEOUT
+ self.response_progress = 0
+ self.response_size = None
+ self.response_transfer_size = None
+
+ self.update_display()
+
+
+ def response_progressed(self, request_receipt):
+ self.response_progress = request_receipt.progress
+ self.response_time = request_receipt.response_time()
+ self.response_size = request_receipt.response_size
+ self.response_transfer_size = request_receipt.response_transfer_size
self.update_display()
def status_text(self):
+ if self.response_transfer_size != None:
+ response_time_str = "{:.2f}".format(self.response_time)
+ stats_string = " "+self.g["page"]+size_str(self.response_size)
+ stats_string += " "+self.g["arrow_d"]+size_str(self.response_transfer_size)+" in "+response_time_str
+ stats_string += "s "+self.g["speed"]+size_str(self.response_transfer_size/self.response_time, suffix="b")+"/s"
+ else:
+ stats_string = ""
+
if self.status == Browser.NO_PATH:
return "No path to destination known"
elif self.status == Browser.PATH_REQUESTED:
@@ -368,10 +428,30 @@ class Browser:
elif self.status == Browser.RECEIVING_RESPONSE:
return "Receiving response..."
elif self.status == Browser.DONE:
- return "Done"
+ return "Done"+stats_string
elif self.status == Browser.DISCONECTED:
return "Disconnected"
else:
return "Browser Status Unknown"
-
\ No newline at end of file
+
+class ResponseProgressBar(urwid.ProgressBar):
+ def get_text(self):
+ return "Receiving response "+super().get_text()
+
+# A convenience function for printing a human-
+# readable file size
+def size_str(num, suffix='B'):
+ units = ['','K','M','G','T','P','E','Z']
+ last_unit = 'Y'
+
+ if suffix == 'b':
+ num *= 8
+ units = ['','K','M','G','T','P','E','Z']
+ last_unit = 'Y'
+
+ for unit in units:
+ if abs(num) < 1000.0:
+ return "%3.2f %s%s" % (num, unit, suffix)
+ num /= 1000.0
+ return "%.2f %s%s" % (num, last_unit, suffix)
\ No newline at end of file

diff --git a/nomadnet/ui/textui/Guide.py b/nomadnet/ui/textui/Guide.py
index 78352a8..5db5222 100644
--- a/nomadnet/ui/textui/Guide.py
+++ b/nomadnet/ui/textui/Guide.py
@@ -70,7 +70,7 @@ class GuideEntry(urwid.WidgetWrap):
widget = ListEntry(topic_name)
urwid.connect_signal(widget, "click", self.display_topic, topic_name)
- style = "list_normal"
+ style = "topic_list_normal"
focus_style = "list_focus"
self.display_widget = urwid.AttrMap(widget, style, focus_style)
urwid.WidgetWrap.__init__(self, self.display_widget)
@@ -155,12 +155,6 @@ TOPIC_INTRODUCTION = '''>Nomad Network
`c`*Communicate Freely.`*
`a
-TODO: REMOVE
-This is a `F07flink `[With a label`344858860838a8d9f8ed:/page/test] to some resource`f.
-This is a link `*`[With a label`:/page/test]`* to some resource.
-This is a link `[With a label`:] to some resource.
-This is a link `*`[With a label`344858860838a8d9f8ed] to some`* resource.
-
The intention with this program is to provide a tool to that allows you to build private and resilient communications platforms that are in complete control and ownership of the people that use them.
Nomad Network is build on LXMF and Reticulum, which together provides the cryptographic mesh functionality and peer-to-peer message routing that Nomad Network relies on. This foundation also makes it possible to use the program over a very wide variety of communication mediums, from packet radio to gigabit fiber.
@@ -417,9 +411,13 @@ TOPIC_MARKUP += "\n`=\n\n>Closing Remarks\n\nIf you made it all the way here, yo
TOPIC_FIRST_RUN = '''>First Time Information
-Hi there. This first run message will only appear once. It contains a few pointers on getting started with Nomad Network, and getting the most out of the program. You're currently located in the guide section of the program. I'm sorry I had to drag you here by force, but it will only happen this one time, I promise. If you ever get lost, return here and peruse the list of topics you see on the left. I will do my best to fill it with answers to mostly anything about Nomad Network.
+Hi there. This first run message will only appear once. It contains a few pointers on getting started with Nomad Network, and getting the most out of the program.
+
+You're currently located in the guide section of the program. I'm sorry I had to drag you here by force, but it will only happen this one time, I promise. If you ever get lost, return here and peruse the list of topics you see on the left. I will do my best to fill it with answers to mostly anything about Nomad Network.
+
+To get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color.
-To get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color. By default, Nomad Network starts in low-color mode. It does this for the sake of compatibility, but it does look rather ugly. If your terminal supports true-color or just 256 colors, you should go to the `![ Config ]`! menu item, launch the editor and change the configuration to use a high-color mode.
+By default, Nomad Network starts in low-color mode. It does this for the sake of compatibility, but it does look rather ugly. If your terminal supports true-color or just 256 colors, you should go to the `![ Config ]`! menu item, launch the editor and change the configuration to use a high-color mode.
If you don't already have a Nerd Font installed (see https://www.nerdfonts.com/), I also highly recommend to do so, since it will greatly expand the amount of glyphs, icons and graphics that Nomad Network can use.

diff --git a/nomadnet/ui/textui/MicronParser.py b/nomadnet/ui/textui/MicronParser.py
index 8ee451f..cd1582b 100644
--- a/nomadnet/ui/textui/MicronParser.py
+++ b/nomadnet/ui/textui/MicronParser.py
@@ -291,7 +291,6 @@ def make_output(state, line, url_delegate):
specname = make_style(state)
speclist = SYNTH_SPECS[specname]
- orig_spec = urwid.AttrSpec('underline', 'default', cm)
if cm == 1:
orig_spec = speclist[0]
elif cm == 16:

diff --git a/setup.py b/setup.py
index fd9d70c..2ff3653 100644
--- a/setup.py
+++ b/setup.py
@@ -23,6 +23,6 @@ setuptools.setup(
entry_points= {
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
},
- install_requires=['rns>=0.2.2', 'lxmf>=0.0.6', 'urwid>=2.1.2'],
- python_requires='>=3.5',
+ install_requires=['rns>=0.2.3', 'lxmf>=0.0.7', 'urwid>=2.1.2'],
+ python_requires='>=3.6',
)
\ No newline at end of file


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────